<?php
/**
 * E-mail gate
 * 
 * @author Martin "DevelX" Jurča
 */
class EmailGate extends Module {
    protected $name = 'EmailGate';
    protected $administrable = true;
    protected $version = '2009-12-20';
    protected $details = array('dependencies' => array(),
            'observes' => array('EmailGate'));

    const TEMPLATES = 'emailgateTemplates';

    private $templatesTable = array('id' => 'iPN+', 'subject' => "v'1024'",
            'header' => 'T', 'footer' => 'T');
    private $templateRecord = array('table' => self::TEMPLATES, 'data' =>
            array());

    /**
     * PHPMailer instance.
     *
     * @var PHPMailer
     */
    private $mailer = null;

    private $isSMTP = false;
    private $host = '';
    private $port = '';
    private $SMTPAuth = '';
    private $username = '';
    private $password = '';

    public function __construct(DBAPI $dbapi, RecordList $recordList) {
        parent::__construct($dbapi, $recordList);
        $this->templateRecord['properties'] = $this->templatesTable;
    }

    public function install() {
        Modules::getModule('Users')->registerRights($this->getName(),
                $this->getRights());
        return $this->dbdriver->createTable(self::TEMPLATES,
                $this->templatesTable);;
    }

    public function uninstall() {
        return $this->dbdriver->dropTable(self::TEMPLATES);
    }

    public function initDisplay($param = null) {
        if (Kernel::getMode() == Kernel::ADMIN) {
            $details = Modules::getModule('View')->getUrl();
            if (count($details) == 1) {
                Modules::getModule('View')->addJS(Config::WEB_DIR .
                        '/utils/tiny_mce/tiny_mce.js');
                Modules::getModule('View')->addJS(Config::WEB_DIR .
                        $this->getDir('/mail.js', true));
            } elseif (count($details) == 2) {
                if ($details[1] == 'add-template') {
                    Modules::getModule('View')->addJS(Config::WEB_DIR .
                            '/utils/tiny_mce/tiny_mce.js');
                    Modules::getModule('View')->addJS(Config::WEB_DIR .
                            $this->getDir('/mail.js', true));
                }
            } elseif (count($details) == 3) {
                if ($details[1] == 'edit-template') {
                    Modules::getModule('View')->addJS(Config::WEB_DIR .
                            '/utils/tiny_mce/tiny_mce.js');
                    Modules::getModule('View')->addJS(Config::WEB_DIR .
                            $this->getDir('/mail.js', true));
                }
            }
        }
    }

    public function display($param = null) {
        if (Kernel::getMode() == Kernel::ADMIN) {
            $this->displayAdmin($param);
        }
    }

    public function setSMTP($smtp, $host, $port, $auth, $user, $password) {
        $this->isSMTP = $smtp;
        $this->host = $host;
        $this->port = $port;
        $this->SMTPAuth = $auth;
        $this->username = $user;
        $this->password = $password;
    }

    /**
     * Sends new HTML e-mail.
     *
     * @param String $from Sender's e-mail address.
     * @param String $fromName Sender's name.
     * @param String $to Reciever's e-mail address.
     * @param String $toName Reciever's name.
     * @param String $subject E-mail subject.
     * @param String $text HTML text of e-mail.
     * @return boolean True on success, false otherwise;
     */
    public function sendMail($from, $fromName, $to, $toName, $subject, $text) {
        if (!$this->hasRights('send mail')) {
            Modules::getModule('View')->addMessage($this->lang(
                    'insufficentRights'), View::MSG_WARNING);
            return false;
        }
        if (strpos($to, '@') === false) {
            return false;
        }
        $plaintext = str_replace('<br>', "\n",
                str_replace('<br />', "\n", $text));
        $plaintext = str_replace('<BR>', "\n",
                str_replace('<BR />', "\n", $text));
        $plaintext = strip_tags($plaintext);
        $plaintext = html_entity_decode($plaintext, ENT_QUOTES, 'UTF-8');
        $mailer = $this->getMailer();
        $mailer->PluginDir = Config::ROOT . '/libs/phpmailer/';
        if ($this->isSMTP) {
            $mailer->Mailer = 'smtp';
            $mailer->Host = $this->host;
            $mailer->Port = $this->port;
            $mailer->SMTPAuth = $this->SMTPAuth;
            $mailer->Username = $this->username;
            $mailer->Password = $this->password;
        }
        $mailer->From = $from;
        $mailer->FromName = $fromName;
        $mailer->Subject = $subject;
        $mailer->ClearAddresses();
        $mailer->AddAddress($to, $toName);
        $mailer->MsgHTML($text);
        $mailer->AltBody = '';
        $mailer->IsHTML();
        return $mailer->Send();
    }

    /**
     * Returns e-mail template as array with keys: subject, header, footer, id
     *
     * @param int $id Template ID number
     * @return Array Template details.
     */
    public function getTemplate($id) {
        $template = $this->templateRecord;
        $template['data']['id'] = (int) $id;
        $this->dbapi->refresh($template);
        return $template['data'];
    }

    /**
     * Returns all templates by pointer.
     *
     * @return Array List of templates.
     */
    public function &getTemplates() {
        $params = array();
        $mails = &$this->recordList->getList($this->templateRecord, $params);
        return $mails;
    }

    public function &onSendMail(&$details, $source) {
        $result = null;
        if (!$this->hasRights('send mail')) {
            Modules::getModule('View')->addMessage($this->lang(
                    'insufficentRights'), View::MSG_ERROR);
            return $result;
        }
        if (!$this->sendMail($details['from'], $details['fromName'],
                $details['to'], $details['toName'], $details['subject'],
                $details['text'])) {
            Modules::getModule('View')->addMessage($this->lang('sendFailed'),
                    View::MSG_ERROR);
        } else {
            Modules::getModule('View')->addMessage($this->lang('sendSuccess'),
                    View::MSG_NOTICE);
        }
        return $result;
    }

    public function &onAddTemplate(&$details, $source) {
        $result = null;
        if (!$this->hasRights('create mail template')) {
            Modules::getModule('View')->addMessage($this->lang(
                    'insufficentRights'), View::MSG_ERROR);
            return $result;
        }
        $template = $this->templateRecord;
        $template['data'] = array('subject' => $details['subject'], 'header' =>
                $details['header'], 'footer' => $details['footer']);
        $this->dbapi->save($template);
        return $result;
    }

    public function &onEditTemplate(&$details, $source) {
        $result = null;
        if (!$this->hasRights('edit mail template')) {
            Modules::getModule('View')->addMessage($this->lang(
                    'insufficentRights'), View::MSG_ERROR);
            return $result;
        }
        $template = $this->templateRecord;
        $template['data'] = array('id' => $details['id'], 'subject' =>
                $details['subject'], 'header' => $details['header'],
                'footer' => $details['footer']);
        $this->dbapi->update($template);
        return $result;
    }

    public function &onDeleteTemplate(&$details, $source) {
        $result = null;
        Kernel::setRedirect($this->getLink());
        if (!$this->hasRights('delete mail template')) {
            Modules::getModule('View')->addMessage($this->lang(
                    'insufficentRights'), View::MSG_ERROR);
            return $result;
        }
        $id = (int) substr($details, 0, -1);
        $template = $this->templateRecord;
        $template['data']['id'] = $id;
        $this->dbapi->delete($template);
        return $result;
    }

    /**
     * Displays administration interface for editing templates.
     *
     * @param int $id Template ID number.
     */
    private function displayAdminEditTemplate($id) {
        if (!$this->hasRights('edit mail template')) {
            return;
        }
        $template = $this->templateRecord;
        $template['data']['id'] = (int) $id;
        $this->dbapi->refresh($template);
        $params = array('formStart' => $this->getForm('editTemplate', true,
                'EmailGate'), 'editTemplateForm' => $this->lang(
                'editTemplateForm'), 'subject' => $this->lang('subject'),
                'header' => $this->lang('header'), 'footer' => $this->lang(
                'footer'), 'save' => $this->lang('save'), 'template' =>
                $template['data']);
        $this->template('edit', $params);
    }

    /**
     * Displays module administration interface.
     *
     * @param mixed $param Display parameter.
     */
    private function displayAdmin($param) {
        if (!$this->hasRights('view admin')) {
            return;
        }
        if ($param == 'submenu') {
            $this->displayAdminSubmenu();
        } else {
            $details = Modules::getModule('View')->getUrl();
            if (count($details) == 1) {
                $this->displayAdminNewMail();
            } elseif (count($details) == 2) {
                if ($details[1] == 'add-template') {
                    $this->displayAdminAddTemplate();
                } elseif ($details[1] == 'templates') {
                    $this->displayAdminTemplates();
                }
            } elseif (count($details) == 3) {
                if ($details[1] == 'edit-template') {
                    $this->displayAdminEditTemplate((int) $details[2]);
                }
            }
        }
    }

    /**
     * Displays administration interface for managing created e-mail templates.
     *
     */
    private function displayAdminTemplates() {
        if (!$this->hasRights('view admin')) {
            return;
        }
        $params = array();
        $templates = $this->recordList->getList($this->templateRecord,
                $params);
        foreach ($templates as &$template) {
            $template['edit'] = $this->getLink(
                    "edit-template/{$template['id']}/");
            $template['delete'] = $this->getLink("{$template['id']}/",
                    'deleteTemplate');
        }
        $params = array('templatesTable' => $this->lang('templatesTable'),
                'templates' => $templates, 'edit' => $this->lang('edit'),
                'delete' => $this->lang('delete'));
        $this->template('templates', $params);
    }

    /**
     * Displays administration interface for adding new templates.
     *
     */
    private function displayAdminAddTemplate() {
        if (!$this->hasRights('create mail template')) {
            return;
        }
        $params = array('formStart' => $this->getForm('addTemplate', true,
                'EmailGate'), 'addTemplateForm' => $this->lang(
                'addTemplateForm'), 'subject' => $this->lang('subject'),
                'header' => $this->lang('header'), 'footer' => $this->lang(
                'footer'), 'create' => $this->lang('create'));
        $this->template('add', $params);
    }

    /**
     * Creates, if required, new PHPMailer instance and initializates it.
     *
     * @return PHPMailer New initialized PHPMailer instance.
     */
    private function getMailer() {
        if ($this->mailer == null) {
            require_once Config::ROOT . '/libs/phpmailer/class.phpmailer.php';
            $this->mailer = new PHPMailer();
            $this->mailer->CharSet = 'utf-8';
        }
        return $this->mailer;
    }

    /**
     * Displays administration interface for creating and sending a new e-mail.
     *
     */
    private function displayAdminNewMail() {
        if (!$this->hasRights('send mail')) {
            return;
        }
        $params = array('formStart' => $this->getForm('sendMail', true,
                'EmailGate'), 'newMailForm' => $this->lang('newMailForm'),
                'fromAddress' => $this->lang('fromAddress'), 'fromName' =>
                $this->lang('fromName'), 'toAddress' => $this->lang(
                'toAddress'), 'toName' => $this->lang('toName'), 'subject' =>
                $this->lang('subject'), 'text' => $this->lang('text'),
                'send' => $this->lang('send'));
        $this->template('newmail', $params);
    }

    /**
     * Displays submenu for module administration.
     *
     */
    private function displayAdminSubmenu() {
        $params = array('menu' => array(array('href' => $this->getLink(),
                'title' => $this->lang('newMailTitle'), 'label' =>
                $this->lang('newMail')), array('href' => $this->getLink(
                'templates/'), 'title' => $this->lang('templatesTitle'),
                'label' => $this->lang('templates')), array('href' => $this->
                getLink('add-template/'), 'title' => $this->lang(
                'addTemplateTitle'), 'label' => $this->lang('addTemplate'))));
        $this->template('submenu', $params);
    }
}
?>
